package tp.badugi.client;

import java.text.Format;
import java.util.Arrays;
import java.util.Scanner;
import java.io.IOException;
import java.io.IOException;
import java.lang.InterruptedException;

import tp.badugi.net.GameStatus;

public class ConsoleClient implements iClientFrontAdapter {
	private Scanner input;
	private iClientBridgeAdapter clientBridge;
	private boolean shutdown = false;
	private String serverIpAddress = "";
	private int serverPort = -1;
	private String typedCommand = "";
	
	
	ConsoleClient(){
		this.input = new Scanner(System.in);
		//this.clientBridge = new ClientBridgeAdapter(new GuiClient());
		
		while(!this.shutdown){
			while(this.serverIpAddress.equals("")){
				this.showConnectionView();
			}
//			while(this.clientBridge.gameStatus == null){
//				this.joinOrCreateTable();
//			}
		}
	}
	
	private void inputCheck(){
		this.typedCommand = this.input.nextLine();
		
		if (this.typedCommand.equals("exit")){
			
			System.out.print("Close program? (Y - type to close)\n");
			this.typedCommand = this.input.nextLine();
			
			if (this.typedCommand.toUpperCase().equals("Y")){
				this.closeProgram();
			}
			else {
				System.out.print("Program closing stopped.\n");
				this.inputCheck();
			}
		}
	}
	
	private void joinOrCreateTable(){
		System.out.print("Type \"connect\" and then id number of table in next line to connect to table.\n"
						+ "Type \"refresh\" to refresh server list.\n"
						+ "Type \"create\" to create new table.");
		
		this.inputCheck();
		switch(this.typedCommand){
			case "connect" : 
				this.joinTable();
				break;
				
//			case "refresh" :
//				this.clientBridge.refreshTableList();
//				break;
				
			case "create" :
				this.createTable();
				break;
				
			default : break;
		}
	}
	
	private void joinTable(){
		String tableName = "";
		this.inputCheck();
		//tableName = this.clientBridge.serverTableList[Integer.parseInt(typedCommand)];
		System.out.print("Type your nickname to join table");
		this.inputCheck();
		try{
			this.clientBridge.joinTable(tableName, this.typedCommand);
		}
		catch(Exception e){
			this.writeErrorMessage("Couldn't join table");
		}
	}
	
	private void createTable(){
		String tableName, myNickname;
		int tableSize;
		long startingChips;
		
		System.out.print("Type table name\n");
		this.inputCheck();
		tableName = this.typedCommand;
		
		System.out.print("Type your game nickname\n");
		this.inputCheck();
		myNickname = this.typedCommand;
		
		System.out.print("Type table size (2 =< tableSize =< 6)\n");
		this.inputCheck();
		tableSize = Integer.parseInt(this.typedCommand);
		
		System.out.print("Type number of chips for each player\n");
		this.inputCheck();
		startingChips = Long.parseLong(this.typedCommand);
		
//		try{
//			this.clientBridge.createTable(tableName, myNickname, tableSize, startingChips);
//		}
//		catch(Exception e){
//			this.writeErrorMessage("Couldn't create table");
//		}
	}
	
	private void closeProgram(){
		System.out.print("Program will close in 5 seconds.\n");
		try{
			for (int i = 0; i < 5; i++){
				System.out.print(".");
				Thread.sleep(1000);
			}
		}
		catch(InterruptedException ie){
			System.out.print("InterruptedException occured while closing!\n"
							+ "Program is clossing immediately.\n");
			this.shutdown = true;
			//this.clientBridge.disconnectAndExitProgram();
			System.exit(1);
		}
		this.shutdown = true;
		//this.clientBridge.disconnectAndExitProgram();
		System.exit(0);
	}

	//------------------------- Server to client
	
	@Override
	public void writeConsoleMessage(String consoleMessage) {
		System.out.print("[Console] "+consoleMessage + "\n");
	}

	@Override
	public void writeErrorMessage(String errorMessage) {
		System.out.print("[ERROR] "+errorMessage + "\n");
	}

	@Override
	public void writeConnectionMessage(String connectionMessage) {
		System.out.print("[CONNECTION] " + connectionMessage + "\n");
	}

	@Override
	public void writeValidationMessage(String validationMessage) {
		System.out.print("[VALIDATION " + validationMessage + "\n");

	}


	public void updateGameData(GameStatus gameStatus) {
		GameStatus g = gameStatus;
		String gameStatusMessage = "[GAME STATUS]\n" 
									+ "TName:" + g.tableName + "Player#: " + g.numberOfPlayers + "; SB: " + g.smallBlind + "; BB: " + g.bigBlind + "\n"
									+ "Round: " + g.bettingRound + "; current pot: " + g.potSize + "; bet: " + g.betAmount + "\n";
		
		for(int i = 0; i < g.numberOfPlayers; i++){
			gameStatusMessage += g.playerNames[i] + " - chips: " + g.playerChipCounts[i] + "; pot contribution: " + g.playerPotContributions[i] + "; status: " + g.playerStatuses[i] + "\n";
		}
		
		gameStatusMessage += "Dealer: " + g.playerNames[g.playerWithDealerButton] + "; player on move: " + g.playerNames[g.playerInAction] + "\n" 
							+ "ME || Nickname: " + g.playerNames[g.myPlayerNumber] + "; Chips: " + g.myChipCount + "; Cards:\n";
		
		for(int i = 0; i < g.myCards.length; i++){
			gameStatusMessage += g.myCards[i] + "     ";
		}
		
		System.out.print(gameStatusMessage);
	}


	public void showRoundWinnerView(String[][] revealedPlayersCards,
			int winnerIndex) {
		String winnerMessage = "[WINNER] " + winnerIndex + "\n"
								+ "Players cards: \n";
		for (int i = 0; i < revealedPlayersCards.length; i++){
			winnerMessage += i;
			for (int j = 0; j < revealedPlayersCards[i].length; j++){
				winnerMessage += " : " + revealedPlayersCards[i][j];
			}
			winnerMessage += "\n";
			
		System.out.print(winnerMessage);
		}
	}

	//------------------------ Client to server
	
	@Override
	public void showConnectionView() {
		System.out.print("Connect to server\n");
		
		System.out.print("IP adress: ");
		this.inputCheck();
		this.serverIpAddress = this.typedCommand;
		
		System.out.print("\nPort number: ");
		this.inputCheck();
		this.serverPort = Integer.parseInt(this.typedCommand);
		
		System.out.print("\nConnecting to " + this.serverIpAddress+ ":" +this.serverPort + "\n");
//		try{
//			this.clientBridge.connect(this.serverIpAddress, this.serverPort);
//		}
//		catch(IOException ioe){
//			this.writeErrorMessage("IOE connection error");
//			this.writeErrorMessage("Connection with server failed");
//			this.serverIpAddress = "";
//			this.serverPort = -1;
//		}
	}

	@Override
	public void showServerView(String serverIpAddress, int serverPortNumber,
			String[] serverList) {
		System.out.print("Table list\n");
		for (int i = 0; i < serverList.length; i++){
			System.out.print(i + ": " +serverList[i] + "\n");
		}
	}

	@Override
	public void showActionView(String[] possibleActions, int timeout,
			long currentBetDifference, long minimalRaise) {
		System.out.print("");

	}

	@Override
	public void showCardChangeView(String[] cards, int timeout) {
		String[] cardsToExchange;
		boolean[] cardsToExchangeIndex = new boolean[4];
		Arrays.fill(cardsToExchangeIndex, false);
		//TODO what size should this String[] be? allways 4?
		// doc says only those to exchange no more
		// do i need to respond to card change request by sending empty String[] ???
		int changedCards = 0;
		int iterator = 0;
		
		
		System.out.print("Choose cards to change (type card number and hit enter to change or type \"done\" to end)\n");
		for(int i = 0; i < cards.length; i++){
			System.out.print(cards[i]);
		}
		System.out.println();
		
		while(!this.typedCommand.equals("done")){
			this.inputCheck();
			switch(this.typedCommand){
				case "1" : cardsToExchangeIndex[1-1] = true;
					break;
				case "2" : cardsToExchangeIndex[2-1] = true;
					break;
				case "3" : cardsToExchangeIndex[3-1] = true;
					break;
				case "4" : cardsToExchangeIndex[4-1] = true;
					break;
				default: break;
			}
		}
		for(int i = 0; i < cardsToExchangeIndex.length; i++){
			if (cardsToExchangeIndex[i] == true)
					changedCards++;
		}
		
		cardsToExchange = new String[changedCards];
		
		while(iterator < changedCards){
			for(int i = 0; i < cardsToExchangeIndex.length; i++){
				if (cardsToExchangeIndex[i] == true)
						cardsToExchange[iterator++] = cards[i];
			}
		}
		
		this.clientBridge.changeCards(cardsToExchange);
	}

	//------------------------ Unused ???
	
	@Override
	public void showGameView(GameStatus gameStatus, String serverIpAdress,
			int serverPortNumber) {
		// TODO Auto-generated method stub
	
	}

	public static void main(String[] args) {
		String clientAuthor = "Hubert W�odarczyk";
		double clientVersion = 0.1;
		
		System.out.print("baDOOGIE started!\n" + "Console client verison: v" + clientVersion + "\n");
		System.out.print("Client made by: " + clientAuthor + "\nAll rights reserved.\n");
		System.out.print("\nHave fun!\n\n");
		
		new ConsoleClient();
	}

	@Override
	public void updateGameData(GameStatus gameStatus, String serverIpAddress,
			int serverPortNumber) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void showRoundWinnerView(String[][] revealedPlayersCards,
			String[] winnersNames, long[] chipsAddedFromPot,
			int[] winnersIndexes) {
		// TODO Auto-generated method stub
		
	}

}
